﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;

namespace MetroToolbox.Interactivity
{
    public static class Interaction
    {
        public static readonly DependencyProperty TriggersProperty = DependencyProperty.RegisterAttached("Triggers", 
            typeof(TriggerCollection), 
            typeof(DependencyObject), 
            new PropertyMetadata(null, TriggersChangedCallback));

        public static TriggerCollection GetTriggers(DependencyObject dependencyObject)
        {
            TriggerCollection collection = (TriggerCollection)dependencyObject.GetValue(TriggersProperty);

            if (collection == null)
            {
                collection = new TriggerCollection();
                dependencyObject.SetValue(TriggersProperty, collection);
            }

            return collection;
        }

        private static void TriggersChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var oldValue = args.OldValue as IAttachedObject;
            var newValue = args.NewValue as IAttachedObject;

            if (oldValue != newValue)
            {
                if (oldValue != null && oldValue.AssociatedObject != null)
                {
                    oldValue.Detach();
                }
                if (newValue != null && dependencyObject != null)
                {
                    if (newValue.AssociatedObject != null)
                    {
                        throw new InvalidOperationException("Object is already attached to an object");
                    }

                    newValue.Attach(dependencyObject);
                }
            }
        }

        public static readonly DependencyProperty BehaviorsProperty = DependencyProperty.RegisterAttached(
            "Behaviors",
            typeof(BehaviorCollection),
            typeof(DependencyObject),
            new PropertyMetadata(null, BehaviorsChangedCallback));

        public static BehaviorCollection GetBehaviors(DependencyObject dependencyObject)
        {
            BehaviorCollection collection = (BehaviorCollection)dependencyObject.GetValue(BehaviorsProperty);

            if (collection == null)
            {
                collection = new BehaviorCollection();
                dependencyObject.SetValue(BehaviorsProperty, collection);
            }

            return collection;
        }

        private static void BehaviorsChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var oldValue = args.OldValue as IAttachedObject;
            var newValue = args.NewValue as IAttachedObject;

            if (oldValue != newValue)
            {
                if (oldValue != null && oldValue.AssociatedObject != null)
                {
                    oldValue.Detach();
                }
                if (newValue != null && dependencyObject != null)
                {
                    if (newValue.AssociatedObject != null)
                    {
                        throw new InvalidOperationException("Object is already attached to an object");
                    }

                    newValue.Attach(dependencyObject);
                }
            }
        }
    }
}
